home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / objcissu.lha / krab-runtime < prev    next >
Internet Message Format  |  1993-02-27  |  40KB

  1. Return-Path: <krab@iesd.auc.dk>
  2. Date: Wed, 10 Feb 1993 03:17:38 +0100
  3. From: Kresten Krab Thorup <krab@iesd.auc.dk>
  4. To: rms@gnu.ai.mit.edu, gnu-objc-submissions@prep.ai.mit.edu
  5. Subject: Gnu objc runtime [comments and bug reports]
  6. Cc: krab@iesd.auc.dk
  7.  
  8. Hi <whoever may recieve this letter> !
  9.  
  10. I have found a number of bugs in the current runtime -- the following
  11. list describes the patch included below.
  12.  
  13.    * class Object *   
  14.  
  15.      # Added methods for alloc/init scheme.  
  16.  
  17.      # Changed isEqual so that bcmp on instances is done, instead of
  18.      comparing the object pointers only.  I dont know if this is the
  19.      right semathics, but it surely is more natural.  
  20.  
  21.      # Changed hash function to be more portable, and so that it only
  22.      uses `self' if it cannot avoid it.  It is a desired property,
  23.      that two isEqual instances gives the same hash value.  
  24.  
  25.      # Added perform with two objects.  
  26.  
  27.      # Fixed subclassResponsibility, notImplemented and
  28.      doesNotRecognize, which didnt sel_getName the selector before it
  29.      was printet!    
  30.  
  31.      # Fixed readFrom so that it does better checking, and gives more
  32.      meaningful error messages.  It now also checks the version. 
  33.  
  34.    * mutex.h * 
  35.  
  36.      # Added support for my own (soon-to-be-released) co routines.
  37.      These are done in ObjC, so it's quite nice...   
  38.   
  39.    * objc-proto.h *  
  40.    
  41.       # Fixed it so that is include'able from objective C code.  It
  42.       wasnt - HOST_BITS_PER_LONG was missing. 
  43.  
  44.    * objc.h *
  45.  
  46.       #  Fixed so that it is include'able from objc code. varargs.h
  47.       was missing. 
  48.  
  49.    * record.h *
  50.  
  51.       #  Fixed two BAD assertions, checking record_entries instead of
  52.       record_capacity. 
  53.  
  54.    * core.c *
  55.  
  56.       # Changed list of included files, so that it may now be compiled
  57.       with an objc compiler.   
  58.  
  59.       # Changed msgSend scheme:  objc_msgSend is now a pointer two a
  60.       function. core.c defines two messengers, one equal to the
  61.       present doing extensively initialization checking, and one
  62.       bare-bone with no such checks (more on initialization at next item)
  63.       This also allows the programmer to do his own messengers -- fun!
  64.  
  65.       # execClass is heavily changed. 
  66.  
  67.         The first time it is called, it installs the heavy version
  68.     of objc_msgSend, so that initialization is handles correctly.
  69.     This one is called __initializing_objc_msgSend -- there is
  70.     also a msgSendSuper with a name like that...
  71.  
  72.     Fixed terrible bug in resolving of class relationship.  In
  73.     line 351, it doesnt check if a class has already been
  74.     resolved, so it will try numerous times... Making only more
  75.     garbage each time.   
  76.  
  77.     Added debugging `printf' displaying cause of failure if
  78.     execClass cannot resolve all classes. 
  79.  
  80.     When all classes have their class-relationships resolved,
  81.     (i.e. the last time it is called), It calls +initialize for
  82.     all classes.  (still using the heavy messenger)  it is not
  83.     called if it has already been done if a +initialize method has
  84.     invoked it indirectly by doing message passing to other
  85.     objects.
  86.  
  87.     Finally, the fast messenger is installed -- we know that all
  88.     classes have been initialized.  This one is called
  89.     __builtin_objc_msgSend -- is such names only for compilers? 
  90.  
  91.       # Changed initialize_class to get a Class_t instead of a class
  92.       names, all invocations said someclass->name, so we can save a
  93.       little in lookup here.   Also the class is marked as initialized
  94.       BEFORE the +initialize method is invoked -- this is needed, if
  95.       that method somehow calls a method in the class it comes from.
  96.  
  97.       # Changed all malloc, calloc etc to either __objc_xmalloc and
  98.       friends, or simply xmalloc and friends.  This gives more control
  99.       of how allocation is done.  Why does malloc come in those two
  100.       flavours anyway?
  101.  
  102.     * hash.c *  
  103.  
  104.       # Changed calloc, malloc into xcalloc, xmalloc -- we _want_
  105.       fatal errors if such things fail...
  106.  
  107.       
  108. This actually makes it possible to compile and run objective C
  109. programs using GNU C.  
  110.  
  111. I am working on a collection library -- it is mostly finished, I'm
  112. writing some documentation currently.   It's designed purely after
  113. Smalltalk, of course with appropriate performance onsiderations.  I
  114. hope to be able to let you test it out for me in the near future.
  115.  
  116. Any comments on the above are stongly appreciated.
  117.  
  118. /Kresten
  119.  
  120. ======================================================================
  121. diff -c ../orig/Object.h objc/Object.h
  122. *** ../orig/Object.h    Tue Feb  9 20:20:19 1993
  123. --- objc/Object.h    Mon Feb  8 21:07:19 1993
  124. ***************
  125. *** 49,54 ****
  126. --- 49,57 ----
  127.   /* Creating, copying, and freeing instances */
  128.   
  129.   + new;
  130. + + alloc;
  131. + - init;
  132.   + free;
  133.   - free;
  134.   - copy;
  135. ***************
  136. *** 62,67 ****
  137. --- 65,71 ----
  138.   - ( Class_t )class;
  139.   - ( Class_t )superClass;
  140.   - ( const char* )name;
  141. + + ( BOOL )isEqual:aClass;
  142.   
  143.   /* Identifying and comparing instances */
  144.   
  145. ***************
  146. *** 85,90 ****
  147. --- 89,95 ----
  148.   
  149.   - perform:( SEL )aSel;
  150.   - perform:( SEL )aSel with:aObject;
  151. + - perform:( SEL )aSel with:firstObject with:secondObject;
  152.   
  153.   /* Posing */
  154.   
  155. diff -c ../orig/mutex.h objc/mutex.h
  156. *** ../orig/mutex.h    Tue Feb  9 20:20:20 1993
  157. --- objc/mutex.h    Tue Feb  9 00:32:13 1993
  158. ***************
  159. *** 36,46 ****
  160.   #define MUTEX_UNLOCK(mutex) mutex_unlock (mutex)
  161.   #define MUTEX_ISLOCK(mutex)     mutex->lock /* Gak */
  162.   
  163. ! #elif defined (OSF)
  164.   
  165. ! #elif defined (mach)
  166.   
  167. ! #elif defined (sun)
  168.   /*
  169.    * Sun lwp uses monitors.
  170.    *
  171. --- 36,46 ----
  172.   #define MUTEX_UNLOCK(mutex) mutex_unlock (mutex)
  173.   #define MUTEX_ISLOCK(mutex)     mutex->lock /* Gak */
  174.   
  175. ! #elif defined (OSF) && !defined (COROUTINES)
  176.   
  177. ! #elif defined (mach) && !defined (COROUTINES)
  178.   
  179. ! #elif defined (sun) && !defined (COROUTINES)
  180.   /*
  181.    * Sun lwp uses monitors.
  182.    *
  183. ***************
  184. *** 86,91 ****
  185. --- 86,102 ----
  186.    * A environment where threads are implemented as a
  187.    *  set of coroutines.
  188.    */
  189. + #include <util/Semaphore.h>   /* this is my co-routine impl (KKT) */
  190. + #define MUTEX Semaphore*
  191. + #define MUTEX_ALLOC(mutex)   { *mutex = [Semaphore alloc]; }
  192. + #define MUTEX_INIT(mutex)    [mutex init]
  193. + #define MUTEX_FREE(mutex)    [mutex free]
  194. + #define MUTEX_LOCK(mutex)    [mutex wait]
  195. + #define MUTEX_ISLOCK(mutex)  [mutex wouldBlock]
  196. + #define MUTEX_UNLOCK(mutex)  [mutex signal]
  197.   
  198.   #endif
  199.   #endif
  200. diff -c ../orig/objc-proto.h objc/objc-proto.h
  201. *** ../orig/objc-proto.h    Tue Feb  9 20:20:20 1993
  202. --- objc/objc-proto.h    Mon Feb  8 11:37:34 1993
  203. ***************
  204. *** 27,32 ****
  205. --- 27,37 ----
  206.   #ifndef __objc_proto_INCLUDE_GNU
  207.   #define __objc_proto_INCLUDE_GNU
  208.   
  209. + #ifndef HOST_BITS_PER_LONG         /* missing? */
  210. + #include <sys/limits.h>
  211. + #define HOST_BITS_PER_LONG (sizeof(long)*CHAR_BIT)
  212. + #endif
  213.   /* This used to be #ifndef __OBJC__, but it turns out that
  214.      object.m needs these declarations.  I don't understand why one
  215.      might want to avoid them in object.m.  */
  216. diff -c ../orig/objc.h objc/objc.h
  217. *** ../orig/objc.h    Tue Feb  9 20:20:20 1993
  218. --- objc/objc.h    Mon Feb  8 11:37:34 1993
  219. ***************
  220. *** 27,32 ****
  221. --- 27,34 ----
  222.   #ifndef __objc_INCLUDE_GNU
  223.   #define __objc_INCLUDE_GNU
  224.   
  225. + #include <varargs.h>
  226.   /* If someone is using a c++ compiler then adjust the types in the
  227.      file back to C.  */
  228.   #ifdef __cplusplus
  229. diff -c ../orig/record.h objc/record.h
  230. *** ../orig/record.h    Tue Feb  9 20:20:21 1993
  231. --- objc/record.h    Tue Feb  9 03:23:10 1993
  232. ***************
  233. *** 92,98 ****
  234.   record_store_at (unsigned int i, void *value, struct record *record)
  235.   {
  236.     assert (i);
  237. !   assert (i <= record_entries (record));
  238.   
  239.     record->records[i] = value;
  240.   }
  241. --- 92,98 ----
  242.   record_store_at (unsigned int i, void *value, struct record *record)
  243.   {
  244.     assert (i);
  245. !   assert (i <= record_capacity (record));
  246.   
  247.     record->records[i] = value;
  248.   }
  249. ***************
  250. *** 121,127 ****
  251.   record_get (unsigned int i, struct record *record)
  252.   {
  253.     assert (i);
  254. !   assert (i <= record_entries (record));
  255.     return record->records[i];
  256.   }
  257.   
  258. --- 121,127 ----
  259.   record_get (unsigned int i, struct record *record)
  260.   {
  261.     assert (i);
  262. !   assert (i <= record_capacity (record));
  263.     return record->records[i];
  264.   }
  265.   
  266. diff -c ../orig/core.c objc/core.c
  267. *** ../orig/core.c    Tue Feb  9 20:20:19 1993
  268. --- objc/core.c    Tue Feb  9 06:27:16 1993
  269. ***************
  270. *** 23,34 ****
  271.      This exception does not however invalidate any other reasons why
  272.      the executable file might be covered by the GNU General Public License.  */
  273.   
  274. - #include "tconfig.h"
  275.   #include "assert.h"
  276.   #include <ctype.h>
  277. ! #include "gstdarg.h"
  278.   #include <stdio.h>
  279. ! #include "gstddef.h"
  280.   
  281.   #include "hash.h"
  282.   #include "objc.h"
  283. --- 23,33 ----
  284.      This exception does not however invalidate any other reasons why
  285.      the executable file might be covered by the GNU General Public License.  */
  286.   
  287.   #include "assert.h"
  288.   #include <ctype.h>
  289. ! #include "stdarg.h"
  290.   #include <stdio.h>
  291. ! #include "stddef.h"
  292.   
  293.   #include "hash.h"
  294.   #include "objc.h"
  295. ***************
  296. *** 56,62 ****
  297.   static SEL    record_selector (const char*);
  298.   static void   record_methods_from_class (Class_t);
  299.   static void   record_methods_from_list (MethodList_t);
  300. ! static void   initialize_class (const char*);
  301.   /*
  302.    * This is a hash table of Class_t structures. 
  303.    *
  304. --- 55,75 ----
  305.   static SEL    record_selector (const char*);
  306.   static void   record_methods_from_class (Class_t);
  307.   static void   record_methods_from_list (MethodList_t);
  308. ! static void   initialize_class (Class_t);
  309. ! /* objc_msgSend comes in 3 variants... */
  310. ! IMP objc_msgSend(id receiver, SEL selector);
  311. ! IMP __builtin_objc_msgSend(id receiver, SEL selector);
  312. ! IMP __initializing_objc_msgSend(id receiver, SEL selector);
  313. ! IMP (*__objc_msgSend)(id receiver, SEL selector) = __initializing_objc_msgSend;
  314. ! /* as does objc_msgSendSuper */
  315. ! IMP objc_msgSendSuper(Super_t receiver, SEL selector);
  316. ! IMP __builtin_objc_msgSendSuper(Super_t receiver, SEL selector);
  317. ! IMP __initializing_objc_msgSendSuper(Super_t receiver, SEL selector);
  318. ! IMP (*__objc_msgSendSuper)(Super_t receiver, SEL selector) =
  319. !        __initializing_objc_msgSendSuper;
  320.   /*
  321.    * This is a hash table of Class_t structures. 
  322.    *
  323. ***************
  324. *** 84,89 ****
  325. --- 97,105 ----
  326.   /* This mutex provides a course lock for method dispatch.  */
  327.   MUTEX    runtimeMutex;
  328.   
  329. + /* This mutex provides lock for malloc and friends */
  330. + MUTEX   mallocMutex;
  331.   /*
  332.    * This hash table is used by the initialization routines.  When the
  333.    * constructor function (__objc_execClass) is called it is passed a pointer
  334. ***************
  335. *** 185,203 ****
  336.     exit (1);
  337.   }
  338.   
  339. ! static void *
  340.   xmalloc (unsigned int size)
  341.   {
  342. !   void *ptr = (void *) malloc (size);
  343.     if (ptr == 0)
  344.       fatal ("virtual memory exceeded");
  345.     return ptr;
  346.   }
  347.   
  348. ! static void *
  349.   xcalloc (unsigned int size, unsigned int units)
  350.   {
  351. !   void *ptr = (void *) calloc (size, units);
  352.     if (ptr == 0)
  353.       fatal ("virtual memory exceeded");
  354.     return ptr;
  355. --- 201,230 ----
  356.     exit (1);
  357.   }
  358.   
  359. !  void *
  360.   xmalloc (unsigned int size)
  361.   {
  362. !   void *ptr;
  363. !   ptr = (void *) malloc (size);
  364. !   if (ptr == 0)
  365. !     fatal ("virtual memory exceeded");
  366. !   return ptr;
  367. ! }
  368. !  void *
  369. ! xrealloc (void* ptr, unsigned int size)
  370. ! {
  371. !   ptr = (void *) realloc (ptr, size);
  372.     if (ptr == 0)
  373.       fatal ("virtual memory exceeded");
  374.     return ptr;
  375.   }
  376.   
  377. !  void *
  378.   xcalloc (unsigned int size, unsigned int units)
  379.   {
  380. !   void *ptr;
  381. !   ptr = (void *) calloc (size, units);
  382.     if (ptr == 0)
  383.       fatal ("virtual memory exceeded");
  384.     return ptr;
  385. ***************
  386. *** 206,212 ****
  387.   void *
  388.   __objc_xmalloc (unsigned int size)
  389.   {
  390. !   void *ptr = (void *) malloc (size);
  391.     if (ptr == 0)
  392.       fatal ("virtual memory exceeded");
  393.     return ptr;
  394. --- 233,240 ----
  395.   void *
  396.   __objc_xmalloc (unsigned int size)
  397.   {
  398. !   void *ptr;
  399. !   ptr = (void *) malloc (size);
  400.     if (ptr == 0)
  401.       fatal ("virtual memory exceeded");
  402.     return ptr;
  403. ***************
  404. *** 215,221 ****
  405.   void *
  406.   __objc_xrealloc (void *optr, unsigned int size)
  407.   {
  408. !   void *ptr = (void *) realloc (optr, size);
  409.     if (ptr == 0)
  410.       fatal ("virtual memory exceeded");
  411.     return ptr;
  412. --- 243,250 ----
  413.   void *
  414.   __objc_xrealloc (void *optr, unsigned int size)
  415.   {
  416. !   void *ptr;
  417. !   ptr = (void *) realloc (optr, size);
  418.     if (ptr == 0)
  419.       fatal ("virtual memory exceeded");
  420.     return ptr;
  421. ***************
  422. *** 224,230 ****
  423.   void *
  424.   __objc_xcalloc (unsigned int size, unsigned int units)
  425.   {
  426. !   void *ptr = (void *) calloc (size, units);
  427.     if (ptr == 0)
  428.       fatal ("virtual memory exceeded");
  429.     return ptr;
  430. --- 253,260 ----
  431.   void *
  432.   __objc_xcalloc (unsigned int size, unsigned int units)
  433.   {
  434. !   void *ptr;
  435. !   ptr = (void *) calloc (size, units);
  436.     if (ptr == 0)
  437.       fatal ("virtual memory exceeded");
  438.     return ptr;
  439. ***************
  440. *** 247,254 ****
  441.    * The purpose of this function is to gather the module pointers so that they
  442.    * may be processed by the initialization clean up routine. 
  443.    */
  444. ! void 
  445. ! __objc_execClass (Module_t module)
  446.   {
  447.     /* Has we processed any constructors previously? 
  448.        Flag used to indicate that some global data structures
  449. --- 277,284 ----
  450.    * The purpose of this function is to gather the module pointers so that they
  451.    * may be processed by the initialization clean up routine. 
  452.    */
  453. ! void            /* it is declared void* in objc-actions.c */
  454. ! __objc_execClass (void* theModule)
  455.   {
  456.     /* Has we processed any constructors previously? 
  457.        Flag used to indicate that some global data structures
  458. ***************
  459. *** 255,260 ****
  460. --- 285,291 ----
  461.        need to be built.  */
  462.     static BOOL previous_constructors = 0;
  463.   
  464. +   Module_t    module = (Module_t)theModule;    /* see above */
  465.     Symtab_t    symtab = module->symtab;
  466.     Class_t     object_class;
  467.     node_ptr node;
  468. ***************
  469. *** 273,287 ****
  470.        some data structures.  */
  471.     if (!previous_constructors) {
  472.   
  473.       /* Enable malloc debugging. This'll slow'er down! */
  474.   #if defined (DEBUG) && defined (NeXT)
  475.       malloc_debug (62);
  476.   #endif
  477.   
  478. -     /* Allocate and initialize the mutex.  */
  479. -     MUTEX_ALLOC (&runtimeMutex);
  480. -     MUTEX_INIT (runtimeMutex);
  481.       /* Allocate the module hash table.  */
  482.       module_hash_table
  483.         = hash_new (MODULE_HASH_SIZE, (hash_func_type)hash_ptr,
  484. --- 304,319 ----
  485.        some data structures.  */
  486.     if (!previous_constructors) {
  487.   
  488. +     __objc_msgSend = __initializing_objc_msgSend; 
  489. +     __objc_msgSendSuper = __initializing_objc_msgSendSuper; 
  490. +                 /* wee need a version checking for */
  491. +                 /* un-initialized classes here... */
  492.       /* Enable malloc debugging. This'll slow'er down! */
  493.   #if defined (DEBUG) && defined (NeXT)
  494.       malloc_debug (62);
  495.   #endif
  496.   
  497.       /* Allocate the module hash table.  */
  498.       module_hash_table
  499.         = hash_new (MODULE_HASH_SIZE, (hash_func_type)hash_ptr,
  500. ***************
  501. *** 348,354 ****
  502.         class1->class_pointer->class_pointer = object_class->class_pointer; 
  503.   
  504.         /* Assign super class pointers */
  505. !       if (class1->super_class) {
  506.       Class_t aSuperClass = objc_getClass ((char*)class1->super_class);
  507.   
  508.       if (aSuperClass) {
  509. --- 380,386 ----
  510.         class1->class_pointer->class_pointer = object_class->class_pointer; 
  511.   
  512.         /* Assign super class pointers */
  513. !       if ((((class1->info)&CLS_RTI)!=CLS_RTI) && class1->super_class) {
  514.       Class_t aSuperClass = objc_getClass ((char*)class1->super_class);
  515.   
  516.       if (aSuperClass) {
  517. ***************
  518. *** 362,375 ****
  519.   
  520.         /* Mark the class as initialized.  */
  521.         class1->info |= CLS_RTI;
  522. !     } else
  523.         /* Couldn't find the class's super class.  */
  524.         incomplete = 1;
  525.         }
  526.       }
  527. !   } else
  528.       /* Couldn't find class Object.  */
  529.       incomplete = 1;
  530.   
  531.     /* Process category information from the module.  */
  532.     for (i = 0; i < symtab->cat_def_cnt; ++i) {
  533. --- 394,413 ----
  534.   
  535.         /* Mark the class as initialized.  */
  536.         class1->info |= CLS_RTI;
  537. !     } else {
  538.         /* Couldn't find the class's super class.  */
  539.         incomplete = 1;
  540. +       DEBUG_PRINTF("Missing superclass for %s (%s)\n",
  541. +                class1->name, (char*)(class1->super_class));
  542. +     }
  543.         }
  544.       }
  545. !   } else {
  546.       /* Couldn't find class Object.  */
  547.       incomplete = 1;
  548. +     DEBUG_PRINTF("Missing class Object\n");
  549. +   }
  550.   
  551.     /* Process category information from the module.  */
  552.     for (i = 0; i < symtab->cat_def_cnt; ++i) {
  553. ***************
  554. *** 396,401 ****
  555. --- 434,440 ----
  556.        be found.  Save the information.  */
  557.         hash_add (&unclaimed_category_hash_table, category, category);
  558.   
  559. +       DEBUG_PRINTF("Missing class %s\n", category->class_name);
  560.         incomplete = 1;
  561.       }
  562.     }
  563. ***************
  564. *** 422,429 ****
  565.         if (category->class_methods)
  566.       addMethodsToClass ((Class_t)class->class_pointer,
  567.                  category->class_methods);
  568. !     } else
  569.         incomplete = 1;
  570.     }
  571.   
  572.     /* Can we finish the run time initialization? */
  573. --- 461,471 ----
  574.         if (category->class_methods)
  575.       addMethodsToClass ((Class_t)class->class_pointer,
  576.                  category->class_methods);
  577. !     } else {
  578. !       DEBUG_PRINTF("Missing class %s\n", category->class_name);
  579.         incomplete = 1;
  580. +     }
  581.     }
  582.   
  583.     /* Can we finish the run time initialization? */
  584. ***************
  585. *** 438,450 ****
  586.       /* Print out class tables if debugging.  */
  587.       DEBUG_PRINTF ("dump of class tables from objcInit\n");
  588.       debug_dump_classes ();
  589. !   }
  590.   
  591.   }
  592.   
  593.   
  594.   IMP  
  595. ! objc_msgSend (id receiver, SEL sel)
  596.   {
  597.     /*
  598.      * A method is always called by the compiler.  If a method wasn't
  599. --- 480,514 ----
  600.       /* Print out class tables if debugging.  */
  601.       DEBUG_PRINTF ("dump of class tables from objcInit\n");
  602.       debug_dump_classes ();
  603. !     /* initialize all classes */
  604. !     for (node = hash_next (class_hash_table, NULL); node;
  605. !      node = hash_next (class_hash_table, node)) 
  606. !       if(!(((Class_t)node->value)->info & CLS_INITIALIZED)) 
  607. !     initialize_class(node->value);
  608. !     __objc_msgSend = __builtin_objc_msgSend; 
  609. !     __objc_msgSendSuper = __builtin_objc_msgSendSuper; 
  610. !                 /* change to the fast versions */
  611.   
  612. +     /* Allocate and initialize the mutex.  */
  613. +     MUTEX_ALLOC (&runtimeMutex);
  614. +     MUTEX_INIT (runtimeMutex);
  615. +     MUTEX_ALLOC(&mallocMutex);
  616. +     MUTEX_INIT(mallocMutex);
  617. +   }
  618.   }
  619.   
  620.   
  621. + IMP objc_msgSend (id receiver, SEL sel) {
  622. +   return (*__objc_msgSend)(receiver,sel);
  623. + }
  624. + /* This is an cut-down messenger, which does only what is needed*/
  625.   IMP  
  626. ! __builtin_objc_msgSend (id receiver, SEL sel)
  627.   {
  628.     /*
  629.      * A method is always called by the compiler.  If a method wasn't
  630. ***************
  631. *** 452,466 ****
  632.      */
  633.     IMP  imp = nil_method;
  634.   
  635.   
  636.     /* The run time must be initialized at this point.
  637.        Otherwise we get a message sent to a object with a bogus selector.  */
  638. !   assert (initialized);
  639.   
  640.     /* Objective-C allows messages to be sent to a nil object.  */
  641.     if (receiver) {
  642.   
  643. !     /* Check for common programmer error.  */
  644.       if (!receiver->class_pointer) {
  645.         fprintf (stderr, "method %s sent to deallocated object %#x\n", 
  646.              sel_getName (sel), receiver);
  647. --- 516,569 ----
  648.      */
  649.     IMP  imp = nil_method;
  650.   
  651. +   /* Objective-C allows messages to be sent to a nil object.  */
  652. +   if (receiver) {
  653. +     /*
  654. +      * If we're passed a object then its class_pointer is a Class.  If
  655. +      * we're passed a Class then its class_pointer is a MetaClass. 
  656. +      * Therefore, searching for a instance or class method
  657. +      * requires no special decision making here. 
  658. +      *
  659. +      * Look for the method. 
  660. +      */
  661. +     imp = get_imp (receiver->class_pointer, sel);
  662. +     /* If the method cannot be found then perform error handling.  */
  663. +     if (!imp)
  664. +       imp = handle_runtime_error (receiver, sel);
  665. +   }
  666. + #ifdef DEBUG
  667. +   /* Nice debugging messages if enabled.  */
  668. +   if (objc_trace) {
  669. +     printf ("trace: objc_msgSend , obj=%#x, class=%s, method=%s\n",
  670. +         receiver, 
  671. +         receiver->class_pointer->name, 
  672. +         sel_getName (sel));
  673. +     fflush (stdout);
  674. +   }
  675. + #endif
  676. +   
  677. +   return imp;
  678. + }
  679. + IMP  
  680. + __initializing_objc_msgSend (id receiver, SEL sel)
  681. + {
  682. +   /*
  683. +    * A method is always called by the compiler.  If a method wasn't
  684. +    * found then supply a default. 
  685. +    */
  686. +   IMP  imp = nil_method;
  687.   
  688.     /* The run time must be initialized at this point.
  689.        Otherwise we get a message sent to a object with a bogus selector.  */
  690. !   assert(initialized);
  691.   
  692.     /* Objective-C allows messages to be sent to a nil object.  */
  693.     if (receiver) {
  694.   
  695. !     /* Check for common programmer error */
  696.       if (!receiver->class_pointer) {
  697.         fprintf (stderr, "method %s sent to deallocated object %#x\n", 
  698.              sel_getName (sel), receiver);
  699. ***************
  700. *** 469,475 ****
  701.       
  702.       /* Initialize the class if need be.  */
  703.       if (!(receiver->class_pointer->info & CLS_INITIALIZED))
  704. !       initialize_class (receiver->class_pointer->name);
  705.   
  706.       /*
  707.        * If we're passed a object then its class_pointer is a Class.  If
  708. --- 572,578 ----
  709.       
  710.       /* Initialize the class if need be.  */
  711.       if (!(receiver->class_pointer->info & CLS_INITIALIZED))
  712. !       initialize_class (receiver->class_pointer);
  713.   
  714.       /*
  715.        * If we're passed a object then its class_pointer is a Class.  If
  716. ***************
  717. *** 494,506 ****
  718.           sel_getName (sel));
  719.       fflush (stdout);
  720.     }
  721. !   
  722.     return imp;
  723.   }
  724.   
  725.   
  726.   IMP 
  727. ! objc_msgSendSuper (Super_t super, SEL sel)
  728.   {
  729.     IMP    imp;
  730.   
  731. --- 597,616 ----
  732.           sel_getName (sel));
  733.       fflush (stdout);
  734.     }
  735.     return imp;
  736.   }
  737.   
  738.   
  739.   IMP 
  740. ! objc_msgSendSuper (Super_t super, SEL sel) {
  741. !   return (__objc_msgSendSuper)(super, sel);
  742. ! }
  743. ! IMP 
  744. ! __initializing_objc_msgSendSuper (Super_t super, SEL sel)
  745.   {
  746.     IMP    imp;
  747.   
  748. ***************
  749. *** 508,516 ****
  750.     assert (initialized);
  751.   
  752.     if (!(super->class->info & CLS_INITIALIZED))
  753. !     initialize_class (super->class->name);
  754.     if (!(super->receiver->class_pointer->info & CLS_INITIALIZED))
  755. !     initialize_class (super->receiver->class_pointer->name);
  756.   
  757.     imp = get_imp (super->class, sel);
  758.     
  759. --- 618,626 ----
  760.     assert (initialized);
  761.   
  762.     if (!(super->class->info & CLS_INITIALIZED))
  763. !     initialize_class (super->class);
  764.     if (!(super->receiver->class_pointer->info & CLS_INITIALIZED))
  765. !     initialize_class (super->receiver->class_pointer);
  766.   
  767.     imp = get_imp (super->class, sel);
  768.     
  769. ***************
  770. *** 528,533 ****
  771. --- 638,653 ----
  772.     return imp;
  773.   }
  774.   
  775. + IMP 
  776. + __builtin_objc_msgSendSuper (Super_t super, SEL sel)
  777. + {
  778. +   IMP    imp;
  779. +   if(imp = get_imp (super->class, sel))
  780. +     return imp;
  781. +   else
  782. +     return handle_runtime_error (super->receiver, sel);
  783. + }
  784.   
  785.   /*
  786.    * This function is called by objc_msgSend or objc_msgSendSuper when a
  787. ***************
  788. *** 634,640 ****
  789.      *
  790.      * No need to initialize the class.  That was done in objcInit. 
  791.      */
  792. !   object = (id) xcalloc (1, class->instance_size);
  793.     object->class_pointer = class;
  794.   
  795.     return object;
  796. --- 754,760 ----
  797.      *
  798.      * No need to initialize the class.  That was done in objcInit. 
  799.      */
  800. !   object = (id) __objc_xcalloc (1, class->instance_size);
  801.     object->class_pointer = class;
  802.   
  803.     return object;
  804. ***************
  805. *** 661,667 ****
  806.     if (length < object->class_pointer->instance_size)
  807.       abort ();
  808.   
  809. !   obj = (id) realloc (object, length);
  810.     bzero ((char*)obj + object->class_pointer->instance_size,  
  811.        length - object->class_pointer->instance_size);
  812.     
  813. --- 781,787 ----
  814.     if (length < object->class_pointer->instance_size)
  815.       abort ();
  816.   
  817. !   obj = (id) __objc_xrealloc (object, length);
  818.     bzero ((char*)obj + object->class_pointer->instance_size,  
  819.        length - object->class_pointer->instance_size);
  820.     
  821. ***************
  822. *** 949,958 ****
  823.   Class_t 
  824.   class_poseAs (Class_t impostor, Class_t super_class)
  825.   {
  826. !   Class_t     new_class = (Class_t) calloc (1, sizeof (Class));
  827. !   MetaClass_t new_meta_class = (MetaClass_t) calloc (1, sizeof (MetaClass));
  828.     node_ptr node;
  829. !   char        *new_name = (char *) malloc (strlen (super_class->name) + 12);
  830.   
  831.     
  832.     assert (new_class);
  833. --- 1069,1078 ----
  834.   Class_t 
  835.   class_poseAs (Class_t impostor, Class_t super_class)
  836.   {
  837. !   Class_t     new_class = (Class_t) __objc_xcalloc (1, sizeof (Class));
  838. !   MetaClass_t new_meta_class = (MetaClass_t) __objc_xcalloc (1, sizeof (MetaClass));
  839.     node_ptr node;
  840. !   char        *new_name = (char *) __objc_xmalloc (strlen (super_class->name) + 12);
  841.   
  842.     
  843.     assert (new_class);
  844. ***************
  845. *** 1220,1235 ****
  846.    * is marked as initialized. 
  847.    */
  848.   static void        
  849. ! initialize_class (const char *name)
  850.   {
  851.     Method_t    method = NULL;
  852. -   Class_t    class = objc_getClass (name);
  853.     SEL        sel = sel_getUid ("initialize");
  854.   
  855.       
  856.     /* The class should not be initialized at this point.  */
  857.     assert (!(class->info & CLS_INITIALIZED));
  858. !   assert (!(class->class_pointer->info & CLS_INITIALIZED));
  859.   
  860.     /* Search for the +initialize method.
  861.        Call it if it exists.  */
  862. --- 1340,1358 ----
  863.    * is marked as initialized. 
  864.    */
  865.   static void        
  866. ! initialize_class (Class_t class)
  867.   {
  868.     Method_t    method = NULL;
  869.     SEL        sel = sel_getUid ("initialize");
  870.   
  871.       
  872.     /* The class should not be initialized at this point.  */
  873.     assert (!(class->info & CLS_INITIALIZED));
  874. !   /*assert (!(class->class_pointer->info & CLS_INITIALIZED));*/
  875. !   /* Mark the class as initialized.  */
  876. !   class->info    |= CLS_INITIALIZED;
  877. !   class->class_pointer->info    |= CLS_INITIALIZED;
  878.   
  879.     /* Search for the +initialize method.
  880.        Call it if it exists.  */
  881. ***************
  882. *** 1240,1254 ****
  883.       IMP    imp;
  884.   
  885.       DEBUG_PRINTF ("Class: %s sending +%s\n", 
  886. !           name, sel_getName (sel));
  887.       imp = get_imp ((Class_t)class->class_pointer, sel);
  888.       assert (imp);
  889.       (*imp)((id)class, sel);
  890.     }
  891.   
  892. -   /* Mark the class as initialized.  */
  893. -   class->info    |= CLS_INITIALIZED;
  894. -   class->class_pointer->info    |= CLS_INITIALIZED;
  895.   }
  896.   
  897.   
  898. --- 1363,1374 ----
  899.       IMP    imp;
  900.   
  901.       DEBUG_PRINTF ("Class: %s sending +%s\n", 
  902. !           class->name, sel_getName (sel));
  903.       imp = get_imp ((Class_t)class->class_pointer, sel);
  904.       assert (imp);
  905.       (*imp)((id)class, sel);
  906.     }
  907.   
  908.   }
  909.   
  910.   
  911. diff -c ../orig/hash.c objc/hash.c
  912. *** ../orig/hash.c    Tue Feb  9 20:20:19 1993
  913. --- objc/hash.c    Tue Feb  9 04:07:26 1993
  914. ***************
  915. *** 23,31 ****
  916.      This exception does not however invalidate any other reasons why
  917.      the executable file might be covered by the GNU General Public License.  */
  918.   
  919. ! #include "tconfig.h"
  920. ! #include "gstddef.h"
  921. ! #include "gstdarg.h"
  922.   #include "assert.h"
  923.   
  924.   #include "hash.h"
  925. --- 23,30 ----
  926.      This exception does not however invalidate any other reasons why
  927.      the executable file might be covered by the GNU General Public License.  */
  928.   
  929. ! #include "stddef.h"
  930. ! #include "stdarg.h"
  931.   #include "assert.h"
  932.   
  933.   #include "hash.h"
  934. ***************
  935. *** 53,67 ****
  936.     assert (size);
  937.     assert (!(size & (size - 1)));
  938.   
  939. !   /* Allocate the cache structure.  calloc insures
  940.        its initialization for default values.  */
  941. !   cache = (cache_ptr) calloc (1, sizeof (struct cache));
  942.     assert (cache);
  943.   
  944.     /* Allocate the array of buckets for the cache.
  945. !      calloc initializes all of the pointers to NULL.  */
  946.     cache->node_table
  947. !     = (node_ptr *) calloc (size, sizeof (node_ptr));
  948.     assert (cache->node_table);
  949.   
  950.     cache->size  = size;
  951. --- 52,66 ----
  952.     assert (size);
  953.     assert (!(size & (size - 1)));
  954.   
  955. !   /* Allocate the cache structure.  xcalloc insures
  956.        its initialization for default values.  */
  957. !   cache = (cache_ptr) xcalloc (1, sizeof (struct cache));
  958.     assert (cache);
  959.   
  960.     /* Allocate the array of buckets for the cache.
  961. !      xcalloc initializes all of the pointers to NULL.  */
  962.     cache->node_table
  963. !     = (node_ptr *) xcalloc (size, sizeof (node_ptr));
  964.     assert (cache->node_table);
  965.   
  966.     cache->size  = size;
  967. ***************
  968. *** 100,106 ****
  969.   hash_add (cache_ptr *cachep, const void *key, void *value)
  970.   {
  971.     size_t indx = (*(*cachep)->hash_func)(*cachep, key);
  972. !   node_ptr node = (node_ptr) calloc (1, sizeof (struct cache_node));
  973.   
  974.   
  975.     assert (node);
  976. --- 99,105 ----
  977.   hash_add (cache_ptr *cachep, const void *key, void *value)
  978.   {
  979.     size_t indx = (*(*cachep)->hash_func)(*cachep, key);
  980. !   node_ptr node = (node_ptr) xcalloc (1, sizeof (struct cache_node));
  981.   
  982.   
  983.     assert (node);
  984. ***************
  985. *** 252,254 ****
  986. --- 251,256 ----
  987.   
  988.     return retval;
  989.   }
  990. diff -c ../orig/object.m objc/object.m
  991. *** ../orig/object.m    Tue Feb  9 20:20:21 1993
  992. --- objc/object.m    Tue Feb  9 03:45:48 1993
  993. ***************
  994. *** 1,3 ****
  995. --- 1,15 ----
  996. + /* This may look like -*- C -*- but it is really objective C */
  997. + /* $Log: Object.m,v $
  998. +  * Revision 1.3  1993/02/08  20:05:15  krab
  999. +  * Changed hash and isEqual to examine instance variables
  1000. +  *
  1001. +  * 6-Feb-1993        Kresten Krab Thorup    
  1002. +  *    Changed deepCopy
  1003. +  * 6-Feb-1993        Kresten Krab Thorup    
  1004. +  *    Changed to alloc/init scheme.  
  1005. +  */
  1006.   /* This file contains the implementation of class Object.
  1007.      Copyright (C) 1992 Free Software Foundation, Inc.
  1008.   
  1009. ***************
  1010. *** 18,26 ****
  1011.   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  1012.    
  1013.   
  1014. ! #include "tconfig.h"
  1015. ! #include "gstdarg.h"
  1016. ! #include "object.h"
  1017.   #include "objc-proto.h"
  1018.   
  1019.   #include <errno.h>
  1020. --- 30,37 ----
  1021.   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  1022.    
  1023.   
  1024. ! #include "stdarg.h"
  1025. ! #include "Object.h"
  1026.   #include "objc-proto.h"
  1027.   
  1028.   #include <errno.h>
  1029. ***************
  1030. *** 34,61 ****
  1031.   @implementation Object
  1032.   
  1033.   
  1034. ! + new
  1035. ! {
  1036. !   return class_createInstance (CLASS (self));
  1037. ! }
  1038.   
  1039.   + free {  return nil; }
  1040.   - free {  return object_dispose (self); }
  1041.   
  1042.   - copy {  return [self shallowCopy]; }
  1043.   
  1044.   - shallowCopy
  1045.   {
  1046.     return object_copy (self);
  1047.   }
  1048.   
  1049.   - deepCopy
  1050.   {
  1051. !   return class_createInstance ([self class]);
  1052.   }
  1053.   
  1054.   
  1055. --- 45,67 ----
  1056.   @implementation Object
  1057.   
  1058.   
  1059. ! + alloc {  return class_createInstance (CLASS (self)); }
  1060. ! + new   {  return [[self alloc] init]; }
  1061. ! - init  {  return self; }
  1062.   
  1063.   + free {  return nil; }
  1064.   - free {  return object_dispose (self); }
  1065.   
  1066.   - copy {  return [self shallowCopy]; }
  1067.   
  1068.   - shallowCopy
  1069.   {
  1070.     return object_copy (self);
  1071.   }
  1072.   
  1073.   - deepCopy
  1074.   {
  1075. !   return object_copy (self);
  1076.   }
  1077.   
  1078.   
  1079. ***************
  1080. *** 69,83 ****
  1081.   
  1082.   - (unsigned int)hash
  1083.   {
  1084. !   return (unsigned int)self; /* gak!  Not portable. */
  1085.   }
  1086.   
  1087.   - (BOOL)isEqual:anObject
  1088.   {
  1089. !   return self == anObject ;
  1090.   }
  1091.   
  1092.   
  1093.   - (BOOL)isKindOf:(Class_t)aClassObject
  1094.   {
  1095. --- 75,104 ----
  1096.   
  1097.   - (unsigned int)hash
  1098.   {
  1099. !   if(isa->instance_size > sizeof(Object))
  1100. !     {
  1101. !       register unsigned cnt, res;
  1102. !       for(cnt=0, res=0; cnt < isa->instance_size; cnt++)
  1103. !     res += ((char*)self)[cnt];
  1104. !       return res;
  1105. !     }
  1106. !   else    /* no instance variables -- use adress */
  1107. !     return ((unsigned int)self)>>3;
  1108.   }
  1109.   
  1110.   - (BOOL)isEqual:anObject
  1111.   {
  1112. !   if(self->isa != anObject->isa) 
  1113. !     return NO;
  1114. !   if(isa->instance_size != anObject->isa->instance_size)
  1115. !     return NO;
  1116. !   return bcmp(self, anObject, isa->instance_size) == 0 ? YES : NO;
  1117.   }
  1118.   
  1119. + + (BOOL)isEqual: aClass
  1120. + {
  1121. +   return self==aClass ? YES : NO;
  1122. + }
  1123.   
  1124.   - (BOOL)isKindOf:(Class_t)aClassObject
  1125.   {
  1126. ***************
  1127. *** 145,150 ****
  1128. --- 166,177 ----
  1129.   }
  1130.   
  1131.   
  1132. + - perform:(SEL)aSel with:aObject with:secondObject
  1133. + {
  1134. +   return (*((IMP)objc_msgSend (self, aSel)))(self, aSel, aObject,secondObject);
  1135. + }
  1136.   + poseAs:(Class_t)aClassObject
  1137.   {
  1138.     return class_poseAs (self, aClassObject);
  1139. ***************
  1140. *** 153,171 ****
  1141.    
  1142.   - subclassResponsibility:(SEL)aSel
  1143.   {
  1144. !   return [self error:"subclass should override %s", aSel];
  1145.   }
  1146.   
  1147.   
  1148.   - notImplemented:(SEL)aSel
  1149.   {
  1150. !   return [self error:"method %s not implemented", aSel];
  1151.   }
  1152.   
  1153.   
  1154.   - doesNotRecognize:(SEL)aSel
  1155.   {
  1156. !   return [self error:"%s does not recognize %s", [self name], aSel];
  1157.   }
  1158.   
  1159.   - error:(const char*)aString, ...
  1160. --- 180,198 ----
  1161.    
  1162.   - subclassResponsibility:(SEL)aSel
  1163.   {
  1164. !   return [self error:"subclass should override %s", sel_getName(aSel)];
  1165.   }
  1166.   
  1167.   
  1168.   - notImplemented:(SEL)aSel
  1169.   {
  1170. !   return [self error:"method %s not implemented", sel_getName(aSel)];
  1171.   }
  1172.   
  1173.   
  1174.   - doesNotRecognize:(SEL)aSel
  1175.   {
  1176. !   return [self error:"%s does not recognize %s", [self name], sel_getName(aSel)];
  1177.   }
  1178.   
  1179.   - error:(const char*)aString, ...
  1180. ***************
  1181. *** 221,226 ****
  1182. --- 248,256 ----
  1183.     return self;
  1184.   }
  1185.   
  1186. +  /* This method reads the header "#<class-name>\0<version>". Finds the */
  1187. +  /* class, and checks it version.  Finally it creates a new instance */
  1188. +  /* of that class, and sends it the message -readFrom: */
  1189.   
  1190.   + readFrom:(int)aFd
  1191.   {
  1192. ***************
  1193. *** 228,234 ****
  1194.     char  objName[256];
  1195.     int   len;
  1196.     
  1197. -   
  1198.     if ((len = read (aFd, &objName, strlen ("#"))) != -1)
  1199.       if (objName[0] == '#') {
  1200.         long  version;
  1201. --- 258,263 ----
  1202. ***************
  1203. *** 243,264 ****
  1204.         if (len != -1)
  1205.           len = read (aFd, &version, sizeof (version));
  1206.         
  1207. !       /* No errors???
  1208. !      Then create a object. */
  1209.         if (len != -1) {
  1210. !     aObj = class_createInstance (objc_getClass (objName));
  1211. !           
  1212. !     /* If the object was 
  1213. !        successfully created then
  1214. !        tell it to dearchive
  1215. !        itself. */
  1216. !     if (aObj)
  1217.         [aObj readFrom:aFd];
  1218.         }
  1219.       }
  1220.       
  1221.     if (len == -1)
  1222. !     [self error:"error activating object, errno=%d", errno];
  1223.     
  1224.     return aObj;
  1225.   }
  1226. --- 272,294 ----
  1227.         if (len != -1)
  1228.           len = read (aFd, &version, sizeof (version));
  1229.         
  1230. !       /* No errors??? Then create a object. */
  1231.         if (len != -1) {
  1232. !     Class_t aClass = objc_getClass(objName);
  1233. !     if(aClass == nil)
  1234. !       [self error: "readFrom: Cannot find class %s", objName];
  1235. !     else if ([aClass version] != version)
  1236. !       [self error: "readFrom: Bad version: %d of class %s", version, objName];
  1237. !     if(aObj = class_createInstance (aClass))
  1238.         [aObj readFrom:aFd];
  1239. +     else
  1240. +       [self error: "readFrom: Cannot create instance of class %s", aClass];
  1241.         }
  1242.       }
  1243.       
  1244.     if (len == -1)
  1245. !     [self error:"readFrom: I/O error activating object, errno=%d", errno];
  1246.     
  1247.     return aObj;
  1248.   }
  1249.  
  1250. Return-Path: <bradcox@sitevax.gmu.edu>
  1251. Date: Wed, 10 Feb 1993 11:51:12 -0500
  1252. To: Kresten Krab Thorup <krab@iesd.auc.dk>, gnu-objc-runtime@prep.ai.mit.edu
  1253. From: bradcox@sitevax.gmu.edu (Brad Cox; 703 968 8229)
  1254. Subject: Re: Gnu objc runtime [comments and bug reports]
  1255. Cc: "Geoffrey S. Knauth" <gsk@marble.com>, rms@gnu.ai.mit.edu,
  1256.         gnu-objc-submissions@prep.ai.mit.edu
  1257.  
  1258. krab@iesd.auc.dk wrote:
  1259. >     # Changed isEqual so that bcmp on instances is done, instead of
  1260. >     comparing the object pointers only.  I dont know if this is the
  1261. >     right semathics, but it surely is more natural.  
  1262.  
  1263. There is no single *right* semantics for isEqual: at the generic Object
  1264. level. You're confusing the difference between fixing a bug and redefining
  1265. a standard.
  1266.  
  1267. I encourage you to undo this fix by adopting (1) the simplest to explain
  1268. (2) the smallest to implement and (3) the one discussed in my book and (4)
  1269. the one adopted in existing Object class implementations; namely that
  1270. unless overridden, equality == identity; i.e.
  1271.  
  1272. - isEqual: anObject { return anObject == self; }
  1273.  
  1274. Don't forget that unfixing isEqual: will also require unfixing hash.
  1275. --
  1276.    Brad Cox; bradcox@sitevax.gmu.edu; 703 993 1142 work 703 968 8229 home 
  1277.  George Mason Program on Social and Organizational Learning; Fairfax VA 22030
  1278.  
  1279.  
  1280. Return-Path: <dglattin@trirex.com>
  1281. Date: Wed, 10 Feb 93 20:57:58 -0800
  1282. From: Dennis Glatting <dglattin@trirex.com>
  1283. To: "Geoffrey S. Knauth" <gsk@marble.com>
  1284. Subject: Re: [krab@iesd.auc.dk: Gnu objc runtime [comments and bug reports]]
  1285. Cc: gnu-objc-runtime@prep.ai.mit.edu
  1286. Reply-To: dennis_glatting@trirex.com
  1287.  
  1288. > # Changed msgSend scheme:  objc_msgSend is now a pointer
  1289. > two a function. core.c defines two messengers, one equal
  1290. > to the present doing extensively initialization
  1291. > checking, and one bare-bone with no such checks (more on
  1292. > initialization at next item) This also allows the
  1293. > programmer to do his own messengers -- fun! 
  1294.  
  1295.  
  1296.  
  1297. Trade off.  Adds overhead to *every* message dispatch.
  1298.  
  1299.  
  1300. > When all classes have their class-relationships
  1301. > resolved, (i.e. the last time it is called), It calls
  1302. > +initialize for all classes.  (still using the heavy
  1303. > messenger)  it is not called if it has already been done if a
  1304. > +initialize method has invoked it indirectly by doing
  1305. > message passing to other objects. 
  1306.  
  1307.  
  1308.  
  1309. This is contrary to the definition of the +initialize.  Also, I did  
  1310. this once.  There are problems.  For example, what if a +initialize  
  1311. method allocates a object of another class?  The +initialize method  
  1312. of the second class hasn't been called yet.  How is the +initialize  
  1313. method of the second class called?  By checking to see if the class  
  1314. has been initialized.  So what's the point of executing all  
  1315. +initialize methods at once?
  1316.  
  1317.  
  1318. -dpg
  1319.  
  1320. Return-Path: <krab@iesd.auc.dk>
  1321. Date: Wed, 24 Feb 1993 09:52:42 +0100
  1322. From: Kresten Krab Thorup <krab@iesd.auc.dk>
  1323. To: Bill Dudney <dudney@pencom.com>
  1324. In-Reply-To: <9302232343.AA02036@>
  1325. Subject: Help with the runtime
  1326. Cc: krab@iesd.auc.dk, rms@gnu.ai.mit.edu, burchard@geom.umn.edu,
  1327.         gsk@marble.com
  1328.  
  1329. Bill Dudney writes:
  1330. >Is there some way I can help? I dont have a very good feel for the
  1331. >state of the run time system now but I do know NeXTs run time pretty
  1332. >well and would be happy to help get GNU's up to snuff.
  1333.  
  1334. Since I don't think the current runtime is worth anything I have
  1335. started writing the runtime from scratch.  As the runtime is only a
  1336. 2-3 thousand lines of C code, I think it would be best if I did it
  1337. alone until I have something which is close to a full runtime.  But
  1338. there are a few points where I really need help.
  1339.  
  1340. (1) Since we do not have a specification of the objective C language
  1341. it is my worst worry if I do it absolutely correct.  There are several
  1342. things which could be done:
  1343.  
  1344.    1) Writing a specification of the objective C language. 
  1345.  
  1346.    2) Writing a specification of the programmer/runtime interface.
  1347.  
  1348. Currently I use the NeXT documentation, and the existing C code to
  1349. make these matters certain.  For example, the exact semathics of
  1350. posing is still a bit unclear to me...  Should the class being posed
  1351. for be accessible in any way after the poseAs call?
  1352.  
  1353.  
  1354. (2) The type encoding format needs revision/redesign.  Stallman, Paul
  1355. and I have had some discussions on this, and if you're interested in
  1356. writing a some documentation, you're welcome.  One problem not exactly
  1357. solved yet, is how to manage translations to and from machine
  1358. independent format, and who's resplonsibility it should be to do so --
  1359. the runtime? the compiler? the code in typedstreams?.  We also need
  1360. someone to actually code things like typed streams.  This is not
  1361. critical for the core runtime, and could be done later.
  1362.  
  1363.  
  1364. (3) Whenever I or other people introduce ideas for new features or how
  1365. to implement them, take your time to evaluate them carefully, and
  1366. ** answer to the gnu-objc list ** , so that we can discuss it in a wide
  1367. forum.  This is the intermediate way to handle (1).
  1368.  
  1369.  
  1370. (4) Once I get something up running, be a *critical* beta-tester.
  1371. This -- I guess -- will take a week or two before I have anything
  1372. presentable to testers.
  1373.  
  1374.  
  1375. Geoffrey:  If you think it would be a good idea, you're welcome to
  1376. post this note to the list.  Perhaps someone has more problems to add? 
  1377.  
  1378. Thanks,
  1379.  
  1380. Kresten
  1381.  
  1382.  
  1383.